﻿using System.Collections.Concurrent;
using Microsoft.AspNetCore.Mvc;

namespace RuoYi.Framework.ApiController;

/// <summary>
///   常量、公共方法配置类
/// </summary>
internal static class Penetrates
{
  /// <summary>
  ///   分组分隔符
  /// </summary>
  internal const string GroupSeparator = "##";

  /// <summary>
  ///   <see cref="IsApiController(Type)" /> 缓存集合
  /// </summary>
  private static readonly ConcurrentDictionary<Type, bool> IsApiControllerCached;

  /// <summary>
  ///   构造函数
  /// </summary>
  static Penetrates()
  {
    ControllerOrderCollection = new ConcurrentDictionary<string, (string, int, Type)>();

    VerbToHttpMethods = new ConcurrentDictionary<string, string>
    {
      ["post"] = "POST",
      ["add"] = "POST",
      ["create"] = "POST",
      ["insert"] = "POST",
      ["submit"] = "POST",

      ["get"] = "GET",
      ["find"] = "GET",
      ["fetch"] = "GET",
      ["query"] = "GET",
      //["getlist"] = "GET",
      //["getall"] = "GET",

      ["put"] = "PUT",
      ["update"] = "PUT",

      ["delete"] = "DELETE",
      ["remove"] = "DELETE",
      ["clear"] = "DELETE",

      ["patch"] = "PATCH"
    };

    IsApiControllerCached = new ConcurrentDictionary<Type, bool>();
  }

  /// <summary>
  ///   请求动词映射字典
  /// </summary>
  internal static ConcurrentDictionary<string, string> VerbToHttpMethods { get; private set; }

  /// <summary>
  ///   控制器排序集合
  /// </summary>
  internal static ConcurrentDictionary<string, (string, int, Type)> ControllerOrderCollection { get; set; }

  /// <summary>
  ///   是否是Api控制器
  /// </summary>
  /// <param name="type">type</param>
  /// <returns></returns>
  internal static bool IsApiController(Type type)
  {
    return IsApiControllerCached.GetOrAdd(type, Function);

    // 本地静态方法
    static bool Function(Type type)
    {
      // 排除 OData 控制器
      if (type.Assembly.GetName().Name.StartsWith("Microsoft.AspNetCore.OData")) return false;

      // 不能是非公开、基元类型、值类型、抽象类、接口、泛型类
      if (!type.IsPublic || type.IsPrimitive || type.IsValueType || type.IsAbstract || type.IsInterface ||
          type.IsGenericType) return false;

      // 继承 ControllerBase  特性
      if (!typeof(Controller).IsAssignableFrom(type) && typeof(ControllerBase).IsAssignableFrom(type)) return true;

      return false;
    }
  }
}
